import os
import logging
from flask import Flask, render_template, request, jsonify
from flask_socketio import SocketIO, emit
from config import MQTT_CONFIG, LOGGING_CONFIG
from mqtt_client import MQTTClientWrapper
import json
import threading

# 配置日志
logging.basicConfig(**LOGGING_CONFIG)
logger = logging.getLogger(__name__)

# 创建Flask应用
app = Flask(__name__)
app.config["SECRET_KEY"] = "your-secret-key-here"
# 明确指定线程模式
socketio = SocketIO(app, cors_allowed_origins="*", async_mode="threading")

# 存储最新的传感器数据和设备状态
sensor_data = {
    "Temperature": "N/A",
    "Humidity": "N/A",
    "Brightness": "N/A",
    "I": "N/A",
    "U": "N/A",
    "W": "N/A",
}
device_status = {"door": "N/A", "window": "N/A", "light": "N/A"}

# 创建线程锁保护共享数据
data_lock = threading.Lock()


# 检查是否是主进程
def is_main_process():
    return not (app.debug and os.environ.get("WERKZEUG_RUN_MAIN") != "true")


# 主界面
@app.route("/")
def index():
    return render_template("index.html")


@app.route("/control")
def control():
    return render_template("control.html")


# 统一控制API接口
@app.route("/api/control", methods=["POST"])
def send_control():
    try:
        data = request.get_json()
        device = data.get("device")
        action = data.get("action")
        if not device or not action:
            return jsonify({"status": "error", "message": "缺少设备或动作参数"}), 400
        command = f"{device}:{action}"
        mqtt_client.publish_control_message(command)
        return jsonify({"status": "success", "command": command})
    except Exception as e:
        logger.error(f"控制API错误: {str(e)}")
        return jsonify({"status": "error", "message": str(e)}), 500


# 安全地更新数据并发送WebSocket事件
def update_and_notify(data):
    try:
        # 使用锁保护共享数据
        with data_lock:
            sensor_data["Temperature"] = data["env"]["tem"]
            sensor_data["Humidity"] = data["env"]["hum"]
            sensor_data["Brightness"] = data["env"]["lux"]
            sensor_data["I"] = data["power"]["I"]
            sensor_data["U"] = data["power"]["U"]
            sensor_data["W"] = data["power"]["W"]
            device_status["door"] = data["status"]["door"]
            device_status["window"] = data["status"]["window"]
            device_status["light"] = data["status"]["light"]
            logger.info("传感器数据和设备状态已更新")

        # 在后台线程中发送WebSocket事件
        socketio.start_background_task(send_data_update)

    except Exception as e:
        logger.error(f"更新数据失败: {str(e)}")


# 发送数据更新事件
def send_data_update():
    try:
        with data_lock:
            combined_data = {**sensor_data, **device_status}
        socketio.emit("data_update", combined_data)
        logger.info("WebSocket数据更新已发送")
    except Exception as e:
        logger.error(f"发送WebSocket事件失败: {str(e)}")


# 处理MQTT消息的回调函数
def handle_mqtt_message(payload):
    try:
        data = json.loads(payload)
        socketio.start_background_task(update_and_notify, data)
    except Exception as e:
        logger.error(f"解析MQTT消息失败: {str(e)}")


# WebSocket连接处理
@socketio.on("connect")
def handle_connect():
    logger.info("客户端已连接")
    # 在后台线程中发送当前数据
    socketio.start_background_task(send_data_update)


# 主应用入口
if __name__ == "__main__":
    # 检查是否为主进程
    if is_main_process():
        logger.info("Starting main application process")

        # 初始化MQTT客户端
        mqtt_client = MQTTClientWrapper(MQTT_CONFIG, sensor_data)
        mqtt_client.handle_mqtt_message = handle_mqtt_message

        logger.info("Flask应用正在启动,访问 http://localhost:5000")
        logger.info("访问控制页面: http://localhost:5000/control")

    # 启动Flask-SocketIO应用
    socketio.run(app, debug=True, host="0.0.0.0")
